home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / emerald / emrldsys.lha / Language / Compiler / builtins.c < prev    next >
C/C++ Source or Header  |  1990-08-16  |  17KB  |  616 lines

  1. /*
  2.  * @(#)builtins.c    1.10  3/13/89
  3.  */
  4. #include "assert.h"
  5. #include "tokens.h"
  6. #include "MyParser.h"
  7. #include "nodes.h"
  8. #include "builtins.h"
  9. #include "buildATs.h"
  10. #include "evaluate.h"
  11. #include "semantics.h"
  12. #include "sequence.h"
  13. #include "symbols.h"
  14. #include "version.h"
  15. #include "environment.h"
  16. #include "opNames.h"
  17. extern char *currentFileName;
  18.  
  19. extern NodePtr buildString();
  20. char *builtinNames[] = {
  21.   "_abstracttypeobject",
  22.   "_anyobject",
  23.   "_arrayobject",
  24.   "_booleanobject",
  25.   "_characterobject",
  26.   "_conditionobject",
  27.   "_integerobject",
  28.   "_nilobject",
  29.   "_nodeobject",
  30.   "_signatureobject",
  31.   "_realobject",
  32.   "_stringobject",
  33.   "_vectorobject",
  34.   "_timeobject",
  35.   "_nodelistelementobject",
  36.   "_nodelistobject",
  37.   "_instreamobject",
  38.   "_outstreamobject",
  39.   "_immutablevectorobject",
  40.   "_bitchunkobject",
  41.   "_riscobject",
  42.   "_handlerobject",
  43.   "_vectorofcharobject",
  44.   "_bufferobject"
  45. };
  46.  
  47. char *builtinTypeNames[] = {
  48.   "abstracttype",
  49.   "any",
  50.   "array",
  51.   "boolean",
  52.   "character",
  53.   "condition",
  54.   "integer",
  55.   "nil",
  56.   "node",
  57.   "signature",
  58.   "real",
  59.   "string",
  60.   "vector",
  61.   "time",
  62.   "nodelistelement",
  63.   "nodelist",
  64.   "instream",
  65.   "outstream",
  66.   "immutablevector",
  67.   "bitchunk",
  68.   "risc",
  69.   "handler",
  70.   "vectorofchar",
  71.   "buffer"
  72. };
  73.  
  74. extern Node
  75.     abstracttypeobject,
  76.     anyobject,
  77.     arrayobject,
  78.     booleanobject,
  79.     characterobject,
  80.     conditionobject,
  81.     integerobject,
  82.     nilobject,
  83.     nodeobject,
  84.     signatureobject,
  85.     realobject,
  86.     stringobject,
  87.     vectorobject,
  88.     timeobject,
  89.     nodelistelementobject,
  90.     nodelistobject,
  91.     instreamobject,
  92.     outstreamobject,
  93.     immutablevectorobject,
  94.     bitchunkobject,
  95.     riscobject,
  96.     handlerobject,
  97.     vectorofcharobject,
  98.     bufferobject;
  99.  
  100. static NodePtr builtins[] = {
  101.   &abstracttypeobject,
  102.   &anyobject,
  103.   &arrayobject,
  104.   &booleanobject,
  105.   &characterobject,
  106.   &conditionobject,
  107.   &integerobject,
  108.   &nilobject, 
  109.   &nodeobject,
  110.   &signatureobject,
  111.   &realobject,
  112.   &stringobject,
  113.   &vectorobject,
  114.   &timeobject,
  115.   &nodelistelementobject,
  116.   &nodelistobject,
  117.   &instreamobject,
  118.   &outstreamobject,
  119.   &immutablevectorobject,
  120.   &bitchunkobject,
  121.   &riscobject,
  122.   &handlerobject,
  123.   &vectorofcharobject,
  124.   &bufferobject
  125. };
  126.  
  127. Boolean conformTable[] = {
  128.   /* abstracttypeobject */    FALSE,
  129.   /* anythingobject */        FALSE,
  130.   /* arrayobject */        FALSE,
  131.   /* booleanobject */        TRUE,
  132.   /* characterobject */        TRUE,
  133.   /* conditionobject */        TRUE,
  134.   /* integerobject */        TRUE,
  135.   /* nilobject */        FALSE,
  136.   /* nodeobject */        TRUE,
  137.   /* signatureobject */        TRUE,
  138.   /* realobject */        TRUE,
  139.   /* stringobject */        TRUE,
  140.   /* vectorobject */        TRUE,
  141.   /* timeobject */        TRUE,
  142.   /* nodelistelementobject */    FALSE,
  143.   /* nodelistobject */        FALSE,
  144.   /* instreamobject */        FALSE,
  145.   /* outstreamobject */        FALSE,
  146.   /* immutablevectorobject */    TRUE,
  147.   /* bitchunkobject */        TRUE,
  148.   /* riscobject */        FALSE,
  149.   /* handlerobject */        FALSE,
  150.   /* vectorofcharobject */    TRUE,
  151.   /* bufferobject */        FALSE
  152. };
  153.  
  154. NodePtr instATOfBuiltins[NUMBUILTINS];
  155. NodePtr instCTOfBuiltins[NUMBUILTINS];
  156. NodePtr ATOfBuiltins[NUMBUILTINS];
  157.  
  158. NodePtr refToBuiltinFromToken(tag, token)
  159. B_Tag tag;
  160. Token token;
  161. {
  162.   register int index;
  163.   switch (token) {
  164.     case KABSTRACTTYPE:
  165.       index = ABSTRACTTYPEINDEX;
  166.       break;
  167.     case KANY:
  168.       index = ANYINDEX;
  169.       break;
  170.     case KARRAY:
  171.       index = ARRAYINDEX;
  172.       break;
  173.     case KBOOLEAN:
  174.       index = BOOLEANINDEX;
  175.       break;
  176.     case KCHARACTER:
  177.       index = CHARACTERINDEX;
  178.       break;
  179.     case KCONDITION:
  180.       index = CONDITIONINDEX;
  181.       break;
  182.     case KINTEGER:
  183.       index = INTEGERINDEX;
  184.       break;
  185.     case KNODE:
  186.       index = NODEINDEX;
  187.       break;
  188.     case KNONE:
  189.       index = NILINDEX;
  190.       break;
  191.     case KNIL:
  192.       index = NILINDEX;
  193.       break;
  194.     case KREAL:
  195.       index = REALINDEX;
  196.       break;
  197.     case KSIGNATURE:
  198.       index = SIGNATUREINDEX;
  199.       break;
  200.     case KSTRING:
  201.       index = STRINGINDEX;
  202.       break;
  203.     case KVECTOR:
  204.       index = VECTORINDEX;
  205.       break;
  206.     case KTIME:
  207.       index = TIMEINDEX;
  208.       break;
  209.     default:
  210.       index = (int) token;
  211.       assert(index >= 0 && index < NUMBUILTINS);
  212.   }
  213.   return(refToBuiltin(tag, index));
  214. }
  215.  
  216. int loadedDummyBuiltins;
  217.  
  218. static NodePtr createDummyAT(id)
  219. OID id;
  220. {
  221.   char namestring[32];
  222.   NodePtr result, name;
  223.   name = Construct(P_SYMDEF, 0);
  224.   result = Construct(P_ATLIT, 4, buildString(currentFileName), NULL, name, NULL);
  225.   sprintf(namestring, "dummy_0x%08x", id);
  226.   name->b.symdef.ident = Ident_Lookup(namestring, strlen(namestring));
  227.   name->b.symdef.symbol = ST_Create(NN, name->b.symdef.ident);
  228.   name->b.symdef.symbol->isManifest = TRUE;
  229.   name->b.symdef.symbol->hasValue = TRUE;
  230.   name->b.symdef.symbol->value.value = result;
  231.   name->b.symdef.symbol->value.ATinfo = refToBuiltin(B_INSTAT, SIGNATUREINDEX);
  232.   name->b.symdef.symbol->value.value = refToBuiltin(B_INSTCT, SIGNATUREINDEX);
  233.   
  234.   defineGlobal(result, id);
  235.   setStage(id, E_Imported);
  236.   return(result);
  237. }
  238.  
  239. static NodePtr createDummyCT(id)
  240. OID id;
  241. {
  242.   NodePtr result;
  243.   result = Construct(P_OBLIT, 10, buildString(currentFileName), NULL, NULL,
  244.     NULL, NULL, NULL, NULL, NULL, NULL, NULL);
  245.   defineGlobal(result, id);
  246.   setStage(id, E_Imported);
  247.   return(result);
  248. }
  249.  
  250. static void loadDummyBuiltins()
  251. {
  252.   register int i;
  253.   register NodePtr b;
  254.   loadedDummyBuiltins = 1;
  255.   for (i = 0; i < NUMBUILTINS; i++) {
  256.     b = builtins[i];
  257.     b->tag = P_OBLIT;
  258.     defineGlobal(b, (OID)BUILTINOBJECTBASE + i);
  259.     setStage((OID)BUILTINOBJECTBASE+i, E_Imported);
  260.     b->b.oblit.instat = createDummyAT(OIDOfBuiltin(B_INSTAT, i));
  261.     instATOfBuiltins[i] = b->b.oblit.instat;
  262.     ATOfBuiltins[i] = createDummyAT(OIDOfBuiltin(B_ITSAT, i));
  263.     if (conformTable[i]) {
  264.       if (i != VECTORINDEX && i != IMMUTABLEVECTORINDEX)
  265.     instCTOfBuiltins[i] = createDummyCT(OIDOfBuiltin(B_INSTCT, i));
  266.     }
  267.   }
  268. }
  269.  
  270. NodePtr figureOutInstCode(s, index)
  271. NodePtr s;
  272. int index;
  273. {
  274.   register NodePtr r, result;
  275.   NodePtr createName;
  276.  
  277.   createName = Construct(P_OPNAME, 0);
  278.   createName->b.opname.id = ON_Translate("create");
  279.   /*
  280.    * Knowing the AT gives us the CT, so we need to load the
  281.    * instCTofBuiltins table with the thing we get by invoking create on
  282.    * this guy.
  283.    */
  284.   r = findObjectOperation(s, createName);
  285.   if (r == NULL) {
  286.     assert(index == NILINDEX || index == NODEINDEX || 
  287.        index == SIGNATUREINDEX || index == ABSTRACTTYPEINDEX ||
  288.        index == ANYINDEX || index == RISCINDEX ||
  289.        index == HANDLERINDEX);
  290.     result = Construct(P_OBLIT, 10, buildString(currentFileName), NULL, NULL,
  291.       NULL, NULL, NULL, NULL, NULL, NULL, NULL);
  292.     setCodeOID(result, INSTCTOFBUILTINOBJECTBASE + index);
  293.   } else {
  294.     assert(r->tag == P_OPDEF);
  295.     r = r->b.opdef.body;
  296.     assert(r->tag == P_BLOCK);
  297.     r = r->b.block.stats;
  298.     assert(r->tag == T_SEQUENCE);
  299.     assert(r->nChildren == 1);
  300.     r = r->b.children[0];
  301.     if (r->tag == P_ASSIGNSTAT) {
  302.       assert(r->b.assignstat.left->tag == T_SEQUENCE);
  303.       assert(r->b.assignstat.left->nChildren == 1);
  304.       assert(r->b.assignstat.right->tag == T_SEQUENCE);
  305.       assert(r->b.assignstat.right->nChildren == 1);
  306.       result = GETVALUE(r->b.assignstat.right->b.children[0]);
  307.       assert(result->tag == P_OBLIT);
  308.       setCodeOID(result, INSTCTOFBUILTINOBJECTBASE + index);
  309.     } else if (r->tag == P_PRIMSTAT) {
  310.       assert(index == CONDITIONINDEX);
  311.       result = Construct(P_OBLIT, 10, buildString(currentFileName), NULL, NULL,
  312.     NULL, NULL, NULL, NULL, NULL, NULL, NULL);
  313.       setCodeOID(result, INSTCTOFBUILTINOBJECTBASE + index);
  314.     } else assert(FALSE);
  315.   }
  316.   return(result);
  317. }
  318.  
  319. NodePtr findInstCode(s)
  320. NodePtr s;
  321. {
  322.   register NodePtr r, result;
  323.   NodePtr createName;
  324.  
  325.   createName = Construct(P_OPNAME, 0);
  326.   createName->b.opname.id = ON_Translate("create");
  327.   /*
  328.    * Knowing the AT gives us the CT, so we need to know the codeOID
  329.    * of the thing we get by invoking create on this guy.
  330.    */
  331.   r = findObjectOperation(s, createName);
  332.   if (r == NULL) return(NULL);
  333.   if (r->tag != P_OPDEF) return(NULL);
  334.   r = r->b.opdef.body;
  335.   if (r->tag != P_BLOCK) return(NULL);
  336.   r = r->b.block.stats;
  337.   if (r->tag != T_SEQUENCE) return(NULL);
  338.   if (r->nChildren != 1) return(NULL);
  339.   r = r->b.children[0];
  340.   if (r->tag != P_ASSIGNSTAT) return(NULL);
  341.   if (r->b.assignstat.left->tag != T_SEQUENCE) return(NULL);
  342.   if (r->b.assignstat.left->nChildren != 1) return(NULL);
  343.   if (r->b.assignstat.right->tag != T_SEQUENCE) return(NULL);
  344.   if (r->b.assignstat.right->nChildren != 1) return(NULL);
  345.   result = r->b.assignstat.right->b.children[0];
  346.   if (result->tag != P_OBLIT) return(NULL);
  347.   return(result);
  348. }
  349.  
  350. NodePtr figureOutOfResult(s)
  351. NodePtr s;
  352. {
  353.   register NodePtr r, result;
  354.   NodePtr ofName;
  355.  
  356.   ofName = Construct(P_OPNAME, 0);
  357.   ofName->b.opname.id = ON_Translate("of");
  358.   /*
  359.    * This is a three level guy, and we want the two level one.
  360.    */
  361.   r = findObjectOperation(s, ofName);
  362.   assert(r != NULL);
  363.   assert(r->tag == P_OPDEF);
  364.   r = r->b.opdef.body;
  365.   assert(r->tag == P_BLOCK);
  366.   r = r->b.block.stats;
  367.   assert(r->tag == T_SEQUENCE);
  368.   assert(r->nChildren == 1);
  369.   r = r->b.children[0];
  370.   assert(r->tag == P_ASSIGNSTAT);
  371.   assert(r->b.assignstat.left->tag == T_SEQUENCE);
  372.   assert(r->b.assignstat.left->nChildren == 1);
  373.   assert(r->b.assignstat.right->tag == T_SEQUENCE);
  374.   assert(r->b.assignstat.right->nChildren == 1);
  375.   result = r->b.assignstat.right->b.children[0];
  376.   assert(result->tag == P_OBLIT);
  377.   /*
  378.    * This used to say
  379.    * setCodeOID(result, OIDOfBuiltin(B_INSTAT, index));
  380.    *
  381.    * it should really just make sure that the code oid is made known in the
  382.    * object table.
  383.    */
  384.   if (getCodeOID(result) != 0) OTInsert(result, getCodeOID(result));
  385.   return(result);
  386. }
  387.  
  388. extern void scanForGlobals();
  389.  
  390. void loadBuiltins()
  391. {
  392.   register int i;
  393.   register NodePtr b;
  394.   NodePtr p, s;
  395.   int *loadBlockPtr, thisBlockSize;
  396.  
  397.   if (builtins[0]->tag == T_NONE) {
  398.     loadDummyBuiltins();
  399.     return;
  400.   }
  401.   loadedDummyBuiltins = 0;
  402.   loadBlockPtr = (int *)&abstracttypeobject;
  403.   loadBlockPtr = loadBlockPtr - 3;
  404.   while (*loadBlockPtr == TREEMAGIC) {
  405.     assert(*(loadBlockPtr + 1) == TREEVERSION);
  406.     thisBlockSize = *(loadBlockPtr + 2);
  407. #ifdef sun
  408.     /* On SunOS4, these are rounded to 8 bytes */
  409. #define roundup(A, B) (((A)+(B)-1) & ~((B) - 1))
  410.     thisBlockSize = roundup(thisBlockSize, 8);
  411. #endif
  412.     p = (NodePtr) (loadBlockPtr + 3);
  413.     assert(p->tag == P_ATLIT || p->tag == P_OBLIT);
  414.     scanForGlobals(p, FALSE);
  415.     loadBlockPtr += (thisBlockSize / 4);
  416.   }
  417.   for (i = 0; i < NUMBUILTINS; i++) {
  418.     b = builtins[i];
  419.     assert(b->b.oblit.id == OIDOfBuiltin(B_IT, i));
  420.     if ((s = b->b.oblit.instat) == NULL) {
  421.       /*
  422.        * This should be a vector or array.
  423.        */
  424.       assert(i == VECTORINDEX || i == ARRAYINDEX || i == IMMUTABLEVECTORINDEX);
  425.       b = figureOutOfResult(b);
  426.       assert(b->tag == P_OBLIT);
  427.     } else {
  428.       assert(b->b.oblit.codeOID == OIDOfBuiltin(B_ITSCT, i));
  429.       s = GETVALUE(s);
  430.       assert(s->tag == P_ATLIT);
  431.       assert(s->b.atlit.id == OIDOfBuiltin(B_INSTAT, i));
  432.       assert(s->b.atlit.f.cannotBeConformedTo == conformTable[i]);
  433.       instATOfBuiltins[i] = s;
  434.       instCTOfBuiltins[i] = figureOutInstCode(b, i);
  435.       if (instCTOfBuiltins[i] != NULL)
  436.     OTInsert(instCTOfBuiltins[i], getCodeOID(instCTOfBuiltins[i]));
  437.       if (conformTable[i]) {
  438.     assert(getCodeOID(instCTOfBuiltins[i]) == getCodeOID(s));
  439.       }
  440.     }
  441.   }
  442. }
  443.  
  444. prepareBuiltinForOutput(s, objectName)
  445. NodePtr s;
  446. char *objectName;
  447. {
  448.   register NodePtr instat, myat, news;
  449.   NodePtr instCode, lp;
  450.   OID theNewOID;
  451.   int i;
  452.  
  453.   /* fix the OID of the object */
  454.   assert(s->tag == P_OBLIT);
  455.   for (i=0; i<NUMBUILTINS && strcmp(objectName,builtinNames[i]); i++);
  456.   assert(i < NUMBUILTINS);
  457.   if (i == VECTOROFCHARINDEX || i == NODELISTINDEX) {
  458.     Symbol st;
  459.     st = s->b.oblit.name->b.symref.symbol;
  460.     st->itsName = objectName;
  461.   }
  462.   theNewOID = BUILTINOBJECTBASE + i;
  463.   Map_Insert(translateOIDMap, (int)s->b.oblit.id, (int)theNewOID);
  464.   defineGlobal(s, theNewOID);
  465.   OTInsert(s, OIDOfBuiltin(B_ITSCT, i));
  466.  
  467.   Map_Delete(environmentMap, (int)OIDOfBuiltin(B_IT, i));
  468.   Map_Delete(environmentMap, (int)OIDOfBuiltin(B_ITSAT, i));
  469.   Map_Delete(environmentMap, (int)OIDOfBuiltin(B_ITSCT, i));
  470.   Map_Delete(environmentMap, (int)OIDOfBuiltin(B_INSTAT, i));
  471.   Map_Delete(environmentMap, (int)OIDOfBuiltin(B_INSTCT, i));
  472.  
  473.   /* and the at of its instances */
  474.   instat = s->b.oblit.instat;
  475.   if (instat == NULL) {
  476.     assert(i == VECTORINDEX || i == ARRAYINDEX || i == IMMUTABLEVECTORINDEX);
  477.     news = figureOutOfResult(s);
  478.     assert(news->tag == P_OBLIT);
  479.  
  480.     /* find the result of getSignature, and set it to conformTable[i] */
  481.     if (conformTable[i]) {
  482.       assert(i == VECTORINDEX || i == IMMUTABLEVECTORINDEX);
  483.       lp = Construct(P_OPNAME, 0);
  484.       lp->b.opname.id = ON_Translate("getsignature");
  485.       lp = findObjectOperation(news, lp);
  486.       assert(lp->tag == P_OPDEF);
  487.       lp = lp->b.opdef.body->b.block.stats->b.children[0];
  488.       assert(lp->tag == P_ASSIGNSTAT);
  489.       lp = lp->b.assignstat.right->b.children[0];
  490.       assert(lp->tag == P_SYMREF);
  491.       lp = lp->b.symref.symbol->value.value;
  492.       assert(lp->tag == P_ATLIT);
  493.       lp->b.atlit.f.cannotBeConformedTo = TRUE;
  494.       lp->b.atlit.f.isVector = TRUE;
  495.     }
  496.  
  497.     /* set the code oid of the builtin object itself */
  498.     setCodeOID(news, OIDOfBuiltin(B_ITSCT, i));
  499.  
  500.     /* set the inst code oid */
  501.     instCode = figureOutInstCode(news, i);
  502.     assert(instCode->tag == P_OBLIT);
  503.     if (! instCode->b.oblit.f.doesNotDuplicateSelf ||
  504.     ! instCode->b.oblit.f.doesNotMoveArguments ||
  505.     ! instCode->b.oblit.f.doesNotMoveSelf) {
  506.       printf("Builtin (%d) with funny flags\n", i);
  507.       instCode->b.oblit.f.doesNotDuplicateSelf = TRUE;
  508.       instCode->b.oblit.f.doesNotMoveArguments = TRUE;
  509.       instCode->b.oblit.f.doesNotMoveSelf = TRUE;
  510.       instCode->b.oblit.f.resultsDependOnlyOnArgs = TRUE;
  511.     }
  512.     if (i == VECTORINDEX || i == IMMUTABLEVECTORINDEX) {
  513.       instCode->b.oblit.f.isVector = TRUE;
  514.     } else {
  515.       instCode->b.oblit.f.isVector = FALSE;
  516.     }
  517.     setCodeOID(instCode, OIDOfBuiltin(B_INSTCT, i));
  518.     OTInsert(instCode, OIDOfBuiltin(B_INSTCT, i));
  519.   } else {
  520.     assert(i != VECTORINDEX && i != ARRAYINDEX && i != IMMUTABLEVECTORINDEX);
  521.     news = s;
  522.     theNewOID = OIDOfBuiltin(B_INSTAT, i);
  523.     if (instat->tag == P_GLOBALREF) {
  524.       resolveGlobal(instat, (ValuePtr)NULL);
  525.       instat->b.globalref.id = theNewOID;
  526.       instat = instat->b.globalref.value;
  527.       assert(instat != NULL);
  528.     }
  529.     assert(instat->tag == P_ATLIT);
  530.     instat->b.atlit.f.cannotBeConformedTo = conformTable[i];
  531.  
  532.     /* set the code oid of the builtin object itself */
  533.     setCodeOID(news, OIDOfBuiltin(B_ITSCT, i));
  534.  
  535.     /* set the inst code oid, and inst code in the at if necessary */
  536.     instCode = figureOutInstCode(news, i);
  537.     assert(instCode->tag == P_OBLIT);
  538.     if (conformTable[i]) setCodeOID(instat, OIDOfBuiltin(B_INSTCT, i));
  539.     assert(instCode != NULL);
  540.     if (i == NODELISTINDEX || i == BITCHUNKINDEX || i == VECTOROFCHARINDEX) {
  541.       instCode->b.oblit.f.isVector = TRUE;
  542.     } else {
  543.       instCode->b.oblit.f.isVector = FALSE;
  544.     }
  545.     setCodeOID(instCode, OIDOfBuiltin(B_INSTCT, i));
  546.     OTInsert(instCode, OIDOfBuiltin(B_INSTCT, i));
  547.  
  548.     if (instCode->b.oblit.name != NULL) {
  549.       assert(instCode->b.oblit.name->tag == P_SYMDEF);
  550.       assert(instCode->b.oblit.name->b.symdef.symbol != NULL);
  551.       assert(instCode->b.oblit.name->b.symdef.symbol->value.ATinfo->tag == P_ATLIT);
  552.       Map_Insert(translateOIDMap,
  553.     (int)instCode->b.oblit.name->b.symdef.symbol->value.ATinfo->b.atlit.id, 
  554.     (int)theNewOID);
  555.       instCode->b.oblit.name->b.symdef.symbol->value.ATinfo = instat;    
  556.     }
  557.     if (instCode->b.oblit.myat != NULL) {
  558.       assert(instCode->b.oblit.myat->tag == P_ATLIT);
  559.       Map_Insert(translateOIDMap,
  560.     (int)instCode->b.oblit.myat->b.atlit.id, 
  561.     (int)theNewOID);
  562.       instCode->b.oblit.myat = instat;    
  563.     }
  564.     Map_Insert(translateOIDMap, (int)instat->b.atlit.id, (int)theNewOID);
  565.     assert(instat->b.atlit.f.writeSeparately);
  566.     defineGlobal(instat, theNewOID);
  567.   }
  568.  
  569.   /* and the at of the object */
  570.   myat = s->b.oblit.myat;
  571.   assert(myat != NULL);
  572.   theNewOID = ATOFBUILTINOBJECTBASE + i;
  573.   if (myat->tag == P_GLOBALREF) {
  574.     resolveGlobal(myat, (ValuePtr)NULL);
  575.     myat->b.globalref.id = theNewOID;
  576.     myat = myat->b.globalref.value;
  577.     assert(myat != NULL);
  578.   }
  579.   assert(myat->tag == P_ATLIT);
  580.   Map_Insert(translateOIDMap, (int)myat->b.atlit.id, (int)theNewOID);
  581.   defineGlobal(myat, theNewOID);
  582. }
  583.  
  584.  
  585. NodePtr refToBuiltin(tag, index)
  586. B_Tag tag;
  587. int index;
  588. {
  589.   register NodePtr r;
  590.   switch (tag) {
  591.     case B_IT:
  592.       r = builtins[index];
  593.       break;
  594.     case B_ITSAT:
  595.       r = ATOfBuiltins[index];
  596.       break;
  597.     case B_ITSCT:
  598.       r = builtins[index];
  599.       break;
  600.     case B_INSTAT:
  601.       r = instATOfBuiltins[index];
  602.       break;
  603.     case B_INSTCT:
  604.       r = instCTOfBuiltins[index];
  605.       if (r == NULL || r->b.oblit.name == NULL) {
  606.     r = Construct(P_GLOBALREF, 0);
  607.     r->b.globalref.id = OIDOfBuiltin(tag, index);
  608.       }
  609.       break;
  610.     default:
  611.       assert(FALSE);
  612.       break;
  613.   }
  614.   return(r);
  615. }
  616.